import {
  Directive,
  OnInit,
  Input,
  ElementRef,
  Renderer2,
  ViewContainerRef,
  ComponentFactory,
  ComponentFactoryResolver,
  TemplateRef,
  ChangeDetectorRef,
  SimpleChanges,
  OnChanges,
  Output,
  EventEmitter,
} from '@angular/core';
import { InputBoolean } from '../core/api';
import { ColorPickerComponent } from './color-picker.component';

@Directive({
  selector: '[lv-color-picker], [lvColorPicker]',
  exportAs: 'lvColorPicker',
})
export class ColorPickerDirective implements OnChanges, OnInit {
  @Input('lvColorPickerClassName') lvClassName: string;

  @Input('lvColorPickerFormat') lvFormat: string = 'hex';

  @Input('lvColorPickerValue') lvValue: string = 'ff0000';

  @Input('lvColorPickerHeader') lvHeader: string | TemplateRef<void> = null;

  @Input('lvColorPickerFooter') lvFooter: string | TemplateRef<void> = null;

  @Input('lvColorPickerShowArrow') @InputBoolean() lvShowArrow: boolean = true;

  @Output('lvColorPickerChange') lvChange: EventEmitter<any> = new EventEmitter();

  @Input('lvColorPickerAnimationType') lvAnimationType: 'popup' | 'slide' = 'popup';

  @Input('lvColorPickerPasteAllowed') @InputBoolean() lvPasteAllowed: boolean = true;

  @Input('lvColorPickerShowColorText') @InputBoolean() lvShowColorText: boolean = true;

  @Output('lvColorPickerValueChange') lvValueChange: EventEmitter<any> = new EventEmitter();

  @Input('lvColorPickerScrollToClose') lvScrollToClose: boolean | { exclusions: HTMLElement[] } = true;

  colorPicker: ColorPickerComponent;
  /**
   * 用于动态创建colorpicker组件，
   */
  protected ComponentFactory: ComponentFactory<ColorPickerComponent> =
    this.resolver.resolveComponentFactory(ColorPickerComponent);

  protected needProxyProperties = [
    'lvHeader',
    'lvFooter',
    'lvScrollToClose',
    'lvShowArrow',
    'lvAnimationType',
    'lvFormat',
    'lvShowColorText',
    'lvPasteAllowed',
    'lvValue',
    'lvClassName',
    'lvValueChange',
    'lvChange',
  ];

  constructor(
    public elementRef: ElementRef,
    protected renderer: Renderer2,
    protected resolver: ComponentFactoryResolver,
    protected ViewContainer: ViewContainerRef,
    protected cdr: ChangeDetectorRef,
  ) {}

  ngOnInit(): void {
    if (!this.colorPicker) {
      this.createComponent();
    }
  }

  ngOnChanges(changes: SimpleChanges): void {
    Object.keys(changes).forEach((key): void => {
      if (changes[key]) {
        this.updateComponentPropertys(key, changes[key].currentValue);
      }
    });

    this.cdr.markForCheck();
  }

  /**
   * 更新directive的属性到component
   */
  private updateComponentPropertys(key: string, value: any): void {
    if (value !== null || value !== undefined) {
      this.colorPicker && (this.colorPicker[key] = value);
    }
  }

  /**
   * 创建colorPicker组件
   */
  private createComponent(): void {
    const tooltipRef = this.ViewContainer.createComponent(this.ComponentFactory);
    this.colorPicker = tooltipRef.instance;
    this.colorPicker.element = this.elementRef.nativeElement;

    // 删除组件的DOM，因为它应该在overlay容器中。
    this.renderer.removeChild(
      this.renderer.parentNode(this.elementRef.nativeElement),
      tooltipRef.location.nativeElement,
    );

    // 更新所有属性到组件
    this.needProxyProperties.forEach((property): void => {
      this.updateComponentPropertys(property, this[property]);
    });
  }
}
